﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EyFramework.Common;
using EyFramework.Sys.Core.Service;
using EyFramework.Sys.Entity;
using EyFramework.Task.Entity;
using EyFramework.Task.Jobs;
using EyFramework.ThirdPart.RedisUtil;
using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using Topshelf;

namespace EyFramework.Task.Starter
{
    public class QuartzServiceRunner : ServiceControl, ServiceSuspend
    {
        private Dictionary<string, IScheduler> commands = new Dictionary<string, IScheduler>();
        private IQrtzCsTaskService qrtzCsTaskService;

        public QuartzServiceRunner()
        {
            qrtzCsTaskService = Globals.GetService<IQrtzCsTaskService>();
        }

        public bool Start(HostControl hostControl)
        {
            //服务器启动后，订阅任务调度命令消息
            RedisHelper.Subscribe(Constants.TASK_CHANNEL, (message) =>
            {
                TaskCommand taskCommand = JsonConvert.DeserializeObject<TaskCommand>(message);
                ScheduleTask(taskCommand);
            });
            //修改服务启动状态
            WinTaskServiceState winTask = new WinTaskServiceState()
            {
                HostName = GetSystemInfo.GetHostName(),
                HostIp = GetSystemInfo.GetClientLocalIPv4Address(),
                RunState = "运行中",
                StartTime = qrtzCsTaskService.GetCurrentDate()
            };

            RedisHelper.Insert<WinTaskServiceState>(TaskConstants.WINSERVER_REDIS_KEY, winTask);
            return true;
        }

        /// <summary>
        /// 执行调度任务
        /// </summary>
        /// <param name="taskCommand"></param>
        private void ScheduleTask(TaskCommand taskCommand)
        {
            QrtzCsTask task = qrtzCsTaskService.GetTaskById(taskCommand.TaskId);
            Console.WriteLine("接收到控制器命令:" + JsonConvert.SerializeObject(taskCommand));
            if (commands.ContainsKey(taskCommand.TaskId))
            {
                if (taskCommand.CommandType == TaskConstants.TASK_COMMAND_暂停)
                {
                    //已经运行过调度任务
                    IScheduler scheduler = commands[taskCommand.TaskId];
                    JobKey jobKey = new JobKey(task.TASK_NAME, task.TASK_GROUP);
                    scheduler.PauseJob(jobKey);
                }
                else if (taskCommand.CommandType == TaskConstants.TASK_COMMAND_恢复)
                {
                    //已经运行过调度任务
                    IScheduler scheduler = commands[taskCommand.TaskId];
                    JobKey jobKey = new JobKey(task.TASK_NAME, task.TASK_GROUP);
                    scheduler.ResumeJob(jobKey);
                }
                else if (taskCommand.CommandType == TaskConstants.TASK_COMMAND_停止)
                {
                    //停止
                    IScheduler scheduler = commands[taskCommand.TaskId];
                    scheduler.Shutdown();
                    commands.Remove(taskCommand.TaskId);
                }
            }
            else
            {
                //还未运行过调度任务
                if (taskCommand.CommandType == TaskConstants.TASK_COMMAND_启动)
                {
                    JobDataMap dataMap = new JobDataMap();
                    dataMap.Put(TaskConstants.TASK_JOBDATAMAP_KEY, task);
                    //运行调度任务
                    IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
                    IJobDetail job = JobBuilder.Create<XseyJob>().WithIdentity(task.TASK_NAME, task.TASK_GROUP)
                        .Build();
                    //创建Trigger
                    ITrigger trigger =
                        TriggerBuilder.Create()
                            .StartAt(System.DateTime.Now)
                            .WithIdentity(task.TASK_NAME, task.TASK_GROUP)
                            .WithCronSchedule(task.CRON)
                            .UsingJobData(dataMap)
                            .Build();
                    //start让调度线程启动
                    scheduler.Start();
                    //将job添加到调度器中，同时将trigger绑定到job
                    scheduler.ScheduleJob(job, trigger).Wait();
                    commands.Add(taskCommand.TaskId, scheduler);
                }
            }
        }

        public bool Stop(HostControl hostControl)
        {
            RedisHelper.Remove(TaskConstants.WINSERVER_REDIS_KEY);
            return true;
        }

        public bool Continue(HostControl hostControl)
        {
            //scheduler.ResumeAll();
            return true;
        }

        public bool Pause(HostControl hostControl)
        {
            //scheduler.PauseAll();
            return true;
        }
    }
}